package cn.harry.cabinet.receiver

import android.annotation.SuppressLint
import android.app.AlarmManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import cn.harry.cabinet.database.AppDatabase
import cn.harry.cabinet.service.AutoRestartService
import cn.harry.cabinet.utils.AppConfigKeys
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

/**
 * 定时重启广播接收器
 * 负责处理定时重启和开机自启动
 */
class AutoRestartReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        val action = intent.action
        
        if (Intent.ACTION_BOOT_COMPLETED == action) {
            // 设备重启后恢复调度
            try {
                CoroutineScope(Dispatchers.IO).launch {
                    val database = AppDatabase.getDatabase(context)
                    val enabled = getAutoRestartEnabled(database)
                    
                    if (enabled) {
                        val hour = getAutoRestartHour(database)
                        val minute = getAutoRestartMinute(database)
                        scheduleDaily(context, hour, minute)
                        Log.i(TAG, "设备重启后已恢复定时重启调度")
                    }
                }
            } catch (e: Exception) {
                Log.e(TAG, "恢复定时重启调度失败: ${e.message}")
            }
            return
        }

        // 触发应用重启
        try {
            val launchIntent = context.packageManager.getLaunchIntentForPackage(context.packageName)
            launchIntent?.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
            
            if (launchIntent != null) {
                context.startActivity(launchIntent)
                Log.i(TAG, "已触发应用重启")
                
                // 重新设置下一个定时任务（用于Android 6.0+的重复任务）
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                    CoroutineScope(Dispatchers.IO).launch {
                        val database = AppDatabase.getDatabase(context)
                        val enabled = getAutoRestartEnabled(database)
                        
                        if (enabled) {
                            val hour = getAutoRestartHour(database)
                            val minute = getAutoRestartMinute(database)
                            scheduleNextRepeating(context, hour, minute)
                            Log.i(TAG, "已重新设置下一个定时重启任务")
                        }
                    }
                }
            } else {
                Log.w(TAG, "未找到启动Intent，无法重启")
            }
        } catch (e: Exception) {
            Log.e(TAG, "执行应用重启失败: ${e.message}")
        }
    }

    companion object {
        private const val TAG = "AutoRestartReceiver"
        private const val REQUEST_CODE = 10086

        /**
         * 设置每天定时重启
         */
        @SuppressLint("ScheduleExactAlarm")
        fun scheduleDaily(context: Context, hour: Int, minute: Int) {
            val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
            val pendingIntent = getPendingIntent(context)

            val now = System.currentTimeMillis()
            val triggerTime = computeNextTriggerTimeMillis(now, hour, minute)

            // 先取消之前的定时任务，避免重复设置
            alarmManager.cancel(pendingIntent)

            // 使用更稳定的API，根据Android版本选择合适的方法
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                // Android 6.0+ 使用 setExactAndAllowWhileIdle 确保在Doze模式下也能工作
                alarmManager.setExactAndAllowWhileIdle(
                    AlarmManager.RTC_WAKEUP,
                    triggerTime,
                    pendingIntent
                )
                // 设置重复任务
                scheduleNextRepeating(context, hour, minute)
            } else {
                // Android 6.0以下使用 setInexactRepeating
                alarmManager.setInexactRepeating(
                    AlarmManager.RTC_WAKEUP,
                    triggerTime,
                    AlarmManager.INTERVAL_DAY,
                    pendingIntent
                )
            }
            
            // 启动前台服务保持应用活跃
            AutoRestartService.startService(context)
            
            Log.i(TAG, "已设置每天定时重启: %02d:%02d".format(hour, minute))
        }

        /**
         * 取消定时重启
         */
        fun cancel(context: Context) {
            val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
            val pendingIntent = getPendingIntent(context)
            alarmManager.cancel(pendingIntent)
            pendingIntent.cancel()
            
            // 停止前台服务
            AutoRestartService.stopService(context)
            
            Log.i(TAG, "已取消定时重启")
        }

        /**
         * 为Android 6.0+设置下一个重复任务
         */
        @RequiresApi(Build.VERSION_CODES.M)
        @SuppressLint("ScheduleExactAlarm")
        private fun scheduleNextRepeating(context: Context, hour: Int, minute: Int) {
            val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
            val pendingIntent = getPendingIntent(context)
            
            // 计算明天的同一时间
            val tomorrow = System.currentTimeMillis() + AlarmManager.INTERVAL_DAY
            val nextTriggerTime = computeNextTriggerTimeMillis(tomorrow, hour, minute)
            
            // 设置明天的任务，并在任务执行时重新设置后天的任务
            alarmManager.setExactAndAllowWhileIdle(
                AlarmManager.RTC_WAKEUP,
                nextTriggerTime,
                pendingIntent
            )
        }

        /**
         * 获取PendingIntent
         */
        private fun getPendingIntent(context: Context): PendingIntent {
            val intent = Intent(context, AutoRestartReceiver::class.java)
            intent.action = "cn.harry.cabinet.ACTION_AUTO_RESTART"
            
            // 使用更稳定的标志组合
            val flags = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
            } else {
                PendingIntent.FLAG_UPDATE_CURRENT
            }
            
            return PendingIntent.getBroadcast(
                context,
                REQUEST_CODE,
                intent,
                flags
            )
        }

        /**
         * 计算下一次触发时间
         */
        private fun computeNextTriggerTimeMillis(now: Long, hour: Int, minute: Int): Long {
            val cal = java.util.Calendar.getInstance()
            cal.timeInMillis = now
            cal.set(java.util.Calendar.SECOND, 0)
            cal.set(java.util.Calendar.MILLISECOND, 0)
            cal.set(java.util.Calendar.HOUR_OF_DAY, hour)
            cal.set(java.util.Calendar.MINUTE, minute)
            if (cal.timeInMillis <= now) {
                cal.add(java.util.Calendar.DAY_OF_YEAR, 1)
            }
            return cal.timeInMillis
        }
        
        /**
         * 从数据库获取自动重启启用状态
         */
        private fun getAutoRestartEnabled(database: AppDatabase): Boolean {
            return try {
                val config = database.configurationDao()
                    .getConfigurationByTypeAndKey(AppConfigKeys.TYPE_SYSTEM, AppConfigKeys.KEY_AUTO_RESTART_ENABLED)
                config?.value?.toBoolean() ?: false
            } catch (e: Exception) {
                Log.e(TAG, "获取自动重启启用状态失败: ${e.message}")
                false
            }
        }
        
        /**
         * 从数据库获取自动重启小时
         */
        private fun getAutoRestartHour(database: AppDatabase): Int {
            return try {
                val config = database.configurationDao()
                    .getConfigurationByTypeAndKey(AppConfigKeys.TYPE_SYSTEM, AppConfigKeys.KEY_AUTO_RESTART_HOUR)
                config?.value?.toIntOrNull() ?: 1
            } catch (e: Exception) {
                Log.e(TAG, "获取自动重启小时失败: ${e.message}")
                1
            }
        }
        
        /**
         * 从数据库获取自动重启分钟
         */
        private fun getAutoRestartMinute(database: AppDatabase): Int {
            return try {
                val config = database.configurationDao()
                    .getConfigurationByTypeAndKey(AppConfigKeys.TYPE_SYSTEM, AppConfigKeys.KEY_AUTO_RESTART_MINUTE)
                config?.value?.toIntOrNull() ?: 0
            } catch (e: Exception) {
                Log.e(TAG, "获取自动重启分钟失败: ${e.message}")
                0
            }
        }
    }
}
